<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>解读Vue框架的源代码</title>
    <!--安装Vue-->
    <script src="js/vue.js"></script>
</head>
<body>

    <!--
    (目前是vue学习的初级阶段,不需要太深入了解原理,大概了解即可,原理到最后一个阶段再说)
     Vue框架源代码中关键性代码
     1.var data = vm.$options.data;
        注意:这是获取data，程序执行到这里的时候vm上还没有 _data属性
     2.data = vm._data = isFunction(data) ? getData(data, vm) : data || {};
        程序执行完这个代码之后,vm对象上多了一个_data这样的属性
        通过以上源码解读,可以得知data不一定是一个{},也可以是一个函数
        代码含义:
            如果data是函数,则调用getData(data,vm)来获取data
            如果data不是函数，则直接将data返回,给data变量,并且同时将data赋值给vm._data属性了
        有一个疑问?
            程序执行到这里,为什么要给vm扩展一个_data属性呢?
                _data属性,是以"_"开始的,足以说明,这个属性是人家Vue框架底层需要访问的
                Vue框架底层他使用vm._data这个属性干啥呢?
                   vm._data是啥?
                   vm._data是:{
                       name : 'jackson',
                       age : 35
                   }
             vm._data这个属性直接指向了底层最真实的data对象,通过_data访问的name和age是不会走数据代理机制的
             通过vm._data方式获取name和age的时候,是不会走getter和setter方法的
       注意:对于Vue实例vm来说,不仅有_data这个属性,还有一个$data属性
                _data是框架内部使用的,可以看做是私有的
                $data这是Vue框架对外公开的一个属性,是给我们程序员使用的
        3.重点函数
             /**
             * Check if a string starts with $ or _
             */
            function isReserved(str) {
                var c = (str + '').charCodeAt(0);
                return c === 0x24 || c === 0x5f;
            }
            这个函数是用来判断字符串是否以 _ 和 $开始的
            true表示以_或者$开始的
            false表示不是以_或者$开始的
       4.proxy(vm , "_data" , key)
            通过这行代码直接进入代理机制(数据代理)
       5.重点函数proxy
         function proxy(target, sourceKey, key) {//target是vm,sourceKey是"_data",key是"age"
            sharedPropertyDefinition.get = function proxyGetter() {
                return this[sourceKey][key];
            };
            sharedPropertyDefinition.set = function proxySetter(val) {
                this[sourceKey][key] = val;
            };
            Object.defineProperty(target, key, sharedPropertyDefinition);
        }

        function proxy(target, sourceKey, key) {//target是vm,sourceKey是"_data",key是"age"
            sharedPropertyDefinition.get = function proxyGetter() {
                return this["_data"]["age"];
            };
            sharedPropertyDefinition.set = function proxySetter(val) {
                this["_data"]["age"] = val;
            };
            Object.defineProperty(vm, 'age, sharedPropertyDefinition);
        }

    -->

<!--容器-->
<div id="app">
    <h1>姓名:{{name}}</h1>
    <h1>年龄:{{age}}</h1>
</div>

<!--vue代码-->
<script>

    //判断当前传递过来的字符串的首字母是否是以 $ 或者 _ 开始的
    function isReserved(str){
        let c = (str + '').charCodeAt(0);
        return c === 0x24 || c === 0x5f;
    }

    console.log(isReserved("$name"))

    const vm = new Vue({
        el : '#app',
        data : {
            name : 'jackson',
            age : 35
        }
    })

    //如果我们程序员不想走代理的方式读取data，想直接读取data当中的数据,可以通过_data和 $data属性来访问
    //建议使用$data这个属性
    console.log('name=' + vm.$data.name)
    console.log('age=' + vm.$data.age)

</script>

</body>
</html>